home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 5 / Apprentice-Release5.iso / Source Code / Pascal / Applications / P4⁄Mac 1.0 / Mac source / block1.p < prev    next >
Encoding:
Text File  |  1994-07-28  |  24.4 KB  |  1,105 lines  |  [TEXT/PJMM]

  1. unit block1;
  2.  
  3. interface
  4.     uses
  5.         pcom1;
  6.  
  7. {procedures that used to be sub-procedures to block.}
  8.     var
  9.         lsy: symbol;
  10.         test: boolean;
  11. {Parameters to block:}
  12. {fsys: setofsys;}
  13. {fsy: symbol;}
  14. {fprocp: ctp;}
  15.  
  16.     procedure skip (fsys: setofsys);
  17.     procedure Bconstant (fsys: setofsys; var fsp: stp; var fvalu: valu);
  18.     function equalbounds (fsp1, fsp2: stp): boolean;
  19.     function comptypes (fsp1, fsp2: stp): boolean;
  20.     function isString (fsp: stp): boolean;
  21.     procedure typ (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  22.     procedure labeldeclaration (fsys: setofsys); {FIX!!!}
  23.     procedure constdeclaration (fsys: setofsys); {FIX!!!}
  24.     procedure typedeclaration (fsys: setofsys); {FIX!!!}
  25.     procedure vardeclaration (fsys: setofsys); {FIX!!!}
  26.  
  27. implementation
  28.  
  29.     procedure skip (fsys: setofsys);
  30.       (*skip input string until relevant symbol found*)
  31.     begin
  32.         if not eof(input) then
  33.             begin
  34.                 while not (sy in fsys) and (not eof(input)) do
  35.                     insymbol;
  36.                 if not (sy in fsys) then
  37.                     insymbol
  38.             end
  39.     end; (*skip*)
  40.  
  41.     procedure Bconstant (fsys: setofsys; var fsp: stp; var fvalu: valu);
  42.         var
  43.             lsp: stp;
  44.             lcp: ctp;
  45.             sign: (none, pos, neg);
  46.             lvp: csp;
  47.             i: 2..strglgth;
  48.     begin
  49.         lsp := nil;
  50.         fvalu.ival := 0;
  51.         if not (sy in constbegsys) then
  52.             begin
  53.                 error(50);
  54.                 skip(fsys + constbegsys)
  55.             end;
  56.         if sy in constbegsys then
  57.             begin
  58.                 if sy = stringconst then
  59.                     begin
  60.                         if lgth = 1 then
  61.                             lsp := charptr
  62.                         else
  63.                             begin
  64.                                 new(lsp, arrays);
  65.                                 with lsp^ do
  66.                                     begin
  67.                                         aeltype := charptr;
  68.                                         inxtype := nil;
  69.                                         size := lgth * charsize;
  70.                                         form := arrays
  71.                                     end
  72.                             end;
  73.                         fvalu := val;
  74.                         insymbol
  75.                     end
  76.                 else
  77.                     begin
  78.                         sign := none;
  79.                         if (sy = addop) and (op in [plus, minus]) then
  80.                             begin
  81.                                 if op = plus then
  82.                                     sign := pos
  83.                                 else
  84.                                     sign := neg;
  85.                                 insymbol
  86.                             end;
  87.                         if sy = ident then
  88.                             begin
  89.                                 searchid([konst], lcp);
  90.                                 with lcp^ do
  91.                                     begin
  92.                                         lsp := idtype;
  93.                                         fvalu := values
  94.                                     end;
  95.                                 if sign <> none then
  96.                                     if lsp = intptr then
  97.                                         begin
  98.                                             if sign = neg then
  99.                                                 fvalu.ival := -fvalu.ival
  100.                                         end
  101.                                     else if lsp = realptr then
  102.                                         begin
  103.                                             if sign = neg then
  104.                                                 begin
  105.                                                     new(lvp, reel);
  106.                                                     if fvalu.valp^.rval[1] = '-' then
  107.                                                         lvp^.rval[1] := '+'
  108.                                                     else
  109.                                                         lvp^.rval[1] := '-';
  110.                                                     for i := 2 to strglgth do
  111.                                                         lvp^.rval[i] := fvalu.valp^.rval[i];
  112.                                                     fvalu.valp := lvp;
  113.                                                 end
  114.                                         end
  115.                                     else
  116.                                         error(105);
  117.                                 insymbol;
  118.                             end
  119.                         else if sy = intconst then
  120.                             begin
  121.                                 if sign = neg then
  122.                                     val.ival := -val.ival;
  123.                                 lsp := intptr;
  124.                                 fvalu := val;
  125.                                 insymbol
  126.                             end
  127.                         else if sy = realconst then
  128.                             begin
  129.                                 if sign = neg then
  130.                                     val.valp^.rval[1] := '-';
  131.                                 lsp := realptr;
  132.                                 fvalu := val;
  133.                                 insymbol
  134.                             end
  135.                         else
  136.                             begin
  137.                                 error(106);
  138.                                 skip(fsys)
  139.                             end
  140.                     end;
  141.                 if not (sy in fsys) then
  142.                     begin
  143.                         error(6);
  144.                         skip(fsys)
  145.                     end
  146.             end;
  147.         fsp := lsp
  148.     end; (*Bconstant*)
  149.  
  150.     function equalbounds (fsp1, fsp2: stp): boolean;
  151.         var
  152.             lmin1, lmin2, lmax1, lmax2: integer;
  153.     begin
  154.         if (fsp1 = nil) or (fsp2 = nil) then
  155.             equalbounds := true
  156.         else
  157.             begin
  158.                 getbounds(fsp1, lmin1, lmax1);
  159.                 getbounds(fsp2, lmin2, lmax2);
  160.                 equalbounds := (lmin1 = lmin2) and (lmax1 = lmax2)
  161.             end
  162.     end; (*equalbounds*)
  163.  
  164.     function comptypes (fsp1, fsp2: stp): boolean;
  165.       (*decide whether structures pointed at by fsp1 and fsp2 are compatible*)
  166.         var
  167.             nxt1, nxt2: ctp;
  168.             comp: boolean;
  169.             ltestp1, ltestp2: testp;
  170.     begin
  171.         if fsp1 = fsp2 then
  172.             comptypes := true
  173.         else if (fsp1 <> nil) and (fsp2 <> nil) then
  174.             if fsp1^.form = fsp2^.form then
  175.                 case fsp1^.form of
  176.                     scalar: 
  177.                         comptypes := false;
  178.         (* identical scalars declared on different levels are}
  179. {         not recognized to be compatible*)
  180.                     subrange: 
  181.                         comptypes := comptypes(fsp1^.rangetype, fsp2^.rangetype);
  182.                     pointer: 
  183.                         begin
  184.                             comp := false;
  185.                             ltestp1 := globtestp;
  186.                             ltestp2 := globtestp;
  187.                             while ltestp1 <> nil do
  188.                                 with ltestp1^ do
  189.                                     begin
  190.                                         if (elt1 = fsp1^.eltype) and (elt2 = fsp2^.eltype) then
  191.                                             comp := true;
  192.                                         ltestp1 := lasttestp
  193.                                     end;
  194.                             if not comp then
  195.                                 begin
  196.                                     new(ltestp1);
  197.                                     with ltestp1^ do
  198.                                         begin
  199.                                             elt1 := fsp1^.eltype;
  200.                                             elt2 := fsp2^.eltype;
  201.                                             lasttestp := globtestp
  202.                                         end;
  203.                                     globtestp := ltestp1;
  204.                                     comp := comptypes(fsp1^.eltype, fsp2^.eltype)
  205.                                 end;
  206.                             comptypes := comp;
  207.                             globtestp := ltestp2
  208.                         end;
  209.                     power: 
  210.                         comptypes := comptypes(fsp1^.elset, fsp2^.elset);
  211.                     arrays: 
  212.                         begin
  213.                             comp := comptypes(fsp1^.aeltype, fsp2^.aeltype) and comptypes(fsp1^.inxtype, fsp2^.inxtype);
  214.                             comptypes := comp and (fsp1^.size = fsp2^.size) and equalbounds(fsp1^.inxtype, fsp2^.inxtype)
  215.                         end;
  216.                     records: 
  217.                         begin
  218.                             nxt1 := fsp1^.fstfld;
  219.                             nxt2 := fsp2^.fstfld;
  220.                             comp := true;
  221.                             while (nxt1 <> nil) and (nxt2 <> nil) do
  222.                                 begin
  223.                                     comp := comp and comptypes(nxt1^.idtype, nxt2^.idtype);
  224.                                     nxt1 := nxt1^.next;
  225.                                     nxt2 := nxt2^.next
  226.                                 end;
  227.                             comptypes := comp and (nxt1 = nil) and (nxt2 = nil) and (fsp1^.recvar = nil) and (fsp2^.recvar = nil)
  228.                         end;
  229.         (*identical records are recognized to be compatible}
  230. {         iff no variants occur*)
  231.                     files: 
  232.                         comptypes := comptypes(fsp1^.filtype, fsp2^.filtype)
  233.                 end (*case*)
  234.             else (*fsp1^.form <> fsp2^.form*)
  235.                 if fsp1^.form = subrange then
  236.                     comptypes := comptypes(fsp1^.rangetype, fsp2)
  237.                 else if fsp2^.form = subrange then
  238.                     comptypes := comptypes(fsp1, fsp2^.rangetype)
  239.                 else
  240.                     comptypes := false
  241.         else
  242.             comptypes := true
  243.     end; (*comptypes*)
  244.  
  245. {"isString" used to be "string", which is reserved in Think Pascal.}
  246. {Is isString a proper name?}
  247. {/Ingemar}
  248.     function isString (fsp: stp): boolean;
  249.     begin
  250.         isString := false;
  251.         if fsp <> nil then
  252.             if fsp^.form = arrays then
  253.                 if comptypes(fsp^.aeltype, charptr) then
  254.                     isString := true
  255.     end; (*isString*)
  256.  
  257.     procedure typ (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  258.         var
  259.             lsp, lsp1, lsp2: stp;
  260.             oldtop: disprange;
  261.             lcp: ctp;
  262.             lsize, displ: addrrange;
  263.             lmin, lmax: integer;
  264.  
  265.         procedure simpletype (fsys: setofsys; var fsp: stp; var fsize: addrrange);
  266.             var
  267.                 lsp, lsp1: stp;
  268.                 lcp, lcp1: ctp;
  269.                 ttop: disprange;
  270.                 lcnt: integer;
  271.                 lvalu: valu;
  272.         begin
  273.             fsize := 1;
  274.             if not (sy in simptypebegsys) then
  275.                 begin
  276.                     error(1);
  277.                     skip(fsys + simptypebegsys)
  278.                 end;
  279.             if sy in simptypebegsys then
  280.                 begin
  281.                     if sy = lparent then
  282.                         begin
  283.                             ttop := top;   (*decl. consts local to innermost block*)
  284.                             while display[top].occur <> blck do
  285.                                 top := top - 1;
  286.                             new(lsp, scalar, declared);
  287.                             with lsp^ do
  288.                                 begin
  289.                                     size := intsize;
  290.                                     form := scalar;
  291.                                     scalkind := declared
  292.                                 end;
  293.                             lcp1 := nil;
  294.                             lcnt := 0;
  295.                             repeat
  296.                                 insymbol;
  297.                                 if sy = ident then
  298.                                     begin
  299.                                         new(lcp, konst);
  300.                                         with lcp^ do
  301.                                             begin
  302.                                                 name := id;
  303.                                                 idtype := lsp;
  304.                                                 next := lcp1;
  305.                                                 values.ival := lcnt;
  306.                                                 klass := konst
  307.                                             end;
  308.                                         enterid(lcp);
  309.                                         lcnt := lcnt + 1;
  310.                                         lcp1 := lcp;
  311.                                         insymbol
  312.                                     end
  313.                                 else
  314.                                     error(2);
  315.                                 if not (sy in fsys + [comma, rparent]) then
  316.                                     begin
  317.                                         error(6);
  318.                                         skip(fsys + [comma, rparent])
  319.                                     end
  320.                             until sy <> comma;
  321.                             lsp^.fconst := lcp1;
  322.                             top := ttop;
  323.                             if sy = rparent then
  324.                                 insymbol
  325.                             else
  326.                                 error(4)
  327.                         end
  328.                     else
  329.                         begin
  330.                             if sy = ident then
  331.                                 begin
  332.                                     searchid([types, konst], lcp);
  333.                                     insymbol;
  334.                                     if lcp^.klass = konst then
  335.                                         begin
  336.                                             new(lsp, subrange);
  337.                                             with lsp^, lcp^ do
  338.                                                 begin
  339.                                                     rangetype := idtype;
  340.                                                     form := subrange;
  341.                                                     if isString(rangetype) then
  342.                                                         begin
  343.                                                             error(148);
  344.                                                             rangetype := nil
  345.                                                         end;
  346.                                                     min := values;
  347.                                                     size := intsize
  348.                                                 end;
  349.                                             if sy = colon then
  350.                                                 insymbol
  351.                                             else
  352.                                                 error(5);
  353.                                             Bconstant(fsys, lsp1, lvalu);
  354.                                             lsp^.max := lvalu;
  355.                                             if lsp^.rangetype <> lsp1 then
  356.                                                 error(107)
  357.                                         end
  358.                                     else
  359.                                         begin
  360.                                             lsp := lcp^.idtype;
  361.                                             if lsp <> nil then
  362.                                                 fsize := lsp^.size
  363.                                         end
  364.                                 end (*sy = ident*)
  365.                             else
  366.                                 begin
  367.                                     new(lsp, subrange);
  368.                                     lsp^.form := subrange;
  369.                                     Bconstant(fsys + [colon], lsp1, lvalu);
  370.                                     if isString(lsp1) then
  371.                                         begin
  372.                                             error(148);
  373.                                             lsp1 := nil
  374.                                         end;
  375.                                     with lsp^ do
  376.                                         begin
  377.                                             rangetype := lsp1;
  378.                                             min := lvalu;
  379.                                             size := intsize
  380.                                         end;
  381.                                     if sy = colon then
  382.                                         insymbol
  383.                                     else
  384.                                         error(5);
  385.                                     Bconstant(fsys, lsp1, lvalu);
  386.                                     lsp^.max := lvalu;
  387.                                     if lsp^.rangetype <> lsp1 then
  388.                                         error(107)
  389.                                 end;
  390.                             if lsp <> nil then
  391.                                 with lsp^ do
  392.                                     if form = subrange then
  393.                                         if rangetype <> nil then
  394.                                             if rangetype = realptr then
  395.                                                 error(399)
  396.                                             else if min.ival > max.ival then
  397.                                                 error(102)
  398.                         end;
  399.                     fsp := lsp;
  400.                     if not (sy in fsys) then
  401.                         begin
  402.                             error(6);
  403.                             skip(fsys)
  404.                         end
  405.                 end
  406.             else
  407.                 fsp := nil
  408.         end; (*simpletype*)
  409.  
  410.         procedure fieldlist (fsys: setofsys; var frecvar: stp);
  411.             var
  412.                 lcp, lcp1, nxt, nxt1: ctp;
  413.                 lsp, lsp1, lsp2, lsp3, lsp4: stp;
  414.                 minsize, maxsize, lsize: addrrange;
  415.                 lvalu: valu;
  416.         begin
  417.             nxt1 := nil;
  418.             lsp := nil;
  419.             if not (sy in (fsys + [ident, casesy])) then
  420.                 begin
  421.                     error(19);
  422.                     skip(fsys + [ident, casesy])
  423.                 end;
  424.             while sy = ident do
  425.                 begin
  426.                     nxt := nxt1;
  427.                     repeat
  428.                         if sy = ident then
  429.                             begin
  430.                                 new(lcp, field);
  431.                                 with lcp^ do
  432.                                     begin
  433.                                         name := id;
  434.                                         idtype := nil;
  435.                                         next := nxt;
  436.                                         klass := field
  437.                                     end;
  438.                                 nxt := lcp;
  439.                                 enterid(lcp);
  440.                                 insymbol
  441.                             end
  442.                         else
  443.                             error(2);
  444.                         if not (sy in [comma, colon]) then
  445.                             begin
  446.                                 error(6);
  447.                                 skip(fsys + [comma, colon, semicolon, casesy])
  448.                             end;
  449.                         test := sy <> comma;
  450.                         if not test then
  451.                             insymbol
  452.                     until test;
  453.                     if sy = colon then
  454.                         insymbol
  455.                     else
  456.                         error(5);
  457.                     typ(fsys + [casesy, semicolon], lsp, lsize);
  458.                     while nxt <> nxt1 do
  459.                         with nxt^ do
  460.                             begin
  461.                                 align(lsp, displ);
  462.                                 idtype := lsp;
  463.                                 fldaddr := displ;
  464.                                 nxt := next;
  465.                                 displ := displ + lsize
  466.                             end;
  467.                     nxt1 := lcp;
  468.                     while sy = semicolon do
  469.                         begin
  470.                             insymbol;
  471.                             if not (sy in fsys + [ident, casesy, semicolon]) then
  472.                                 begin
  473.                                     error(19);
  474.                                     skip(fsys + [ident, casesy])
  475.                                 end
  476.                         end
  477.                 end; (*while*)
  478.             nxt := nil;
  479.             while nxt1 <> nil do
  480.                 with nxt1^ do
  481.                     begin
  482.                         lcp := next;
  483.                         next := nxt;
  484.                         nxt := nxt1;
  485.                         nxt1 := lcp
  486.                     end;
  487.             if sy = casesy then
  488.                 begin
  489.                     new(lsp, tagfld);
  490.                     with lsp^ do
  491.                         begin
  492.                             tagfieldp := nil;
  493.                             fstvar := nil;
  494.                             form := tagfld
  495.                         end;
  496.                     frecvar := lsp;
  497.                     insymbol;
  498.                     if sy = ident then
  499.                         begin
  500.                             new(lcp, field);
  501.                             with lcp^ do
  502.                                 begin
  503.                                     name := id;
  504.                                     idtype := nil;
  505.                                     klass := field;
  506.                                     next := nil;
  507.                                     fldaddr := displ
  508.                                 end;
  509.                             enterid(lcp);
  510.                             insymbol;
  511.                             if sy = colon then
  512.                                 insymbol
  513.                             else
  514.                                 error(5);
  515.                             if sy = ident then
  516.                                 begin
  517.                                     searchid([types], lcp1);
  518.                                     lsp1 := lcp1^.idtype;
  519.                                     if lsp1 <> nil then
  520.                                         begin
  521.                                             align(lsp1, displ);
  522.                                             lcp^.fldaddr := displ;
  523.                                             displ := displ + lsp1^.size;
  524.                                             if (lsp1^.form <= subrange) or isString(lsp1) then
  525.                                                 begin
  526.                                                     if comptypes(realptr, lsp1) then
  527.                                                         error(109)
  528.                                                     else if isString(lsp1) then
  529.                                                         error(399);
  530.                                                     lcp^.idtype := lsp1;
  531.                                                     lsp^.tagfieldp := lcp;
  532.                                                 end
  533.                                             else
  534.                                                 error(110);
  535.                                         end;
  536.                                     insymbol;
  537.                                 end
  538.                             else
  539.                                 begin
  540.                                     error(2);
  541.                                     skip(fsys + [ofsy, lparent])
  542.                                 end
  543.                         end
  544.                     else
  545.                         begin
  546.                             error(2);
  547.                             skip(fsys + [ofsy, lparent])
  548.                         end;
  549.                     lsp^.size := displ;
  550.                     if sy = ofsy then
  551.                         insymbol
  552.                     else
  553.                         error(8);
  554.                     lsp1 := nil;
  555.                     minsize := displ;
  556.                     maxsize := displ;
  557.                     repeat
  558.                         lsp2 := nil;
  559.                         if not (sy in fsys + [semicolon]) then
  560.                             begin
  561.                                 repeat
  562.                                     Bconstant(fsys + [comma, colon, lparent], lsp3, lvalu);
  563.                                     if lsp^.tagfieldp <> nil then
  564.                                         if not comptypes(lsp^.tagfieldp^.idtype, lsp3) then
  565.                                             error(111);
  566.                                     new(lsp3, variant);
  567.                                     with lsp3^ do
  568.                                         begin
  569.                                             nxtvar := lsp1;
  570.                                             subvar := lsp2;
  571.                                             varval := lvalu;
  572.                                             form := variant
  573.                                         end;
  574.                                     lsp4 := lsp1;
  575.                                     while lsp4 <> nil do
  576.                                         with lsp4^ do
  577.                                             begin
  578.                                                 if varval.ival = lvalu.ival then
  579.                                                     error(178);
  580.                                                 lsp4 := nxtvar
  581.                                             end;
  582.                                     lsp1 := lsp3;
  583.                                     lsp2 := lsp3;
  584.                                     test := sy <> comma;
  585.                                     if not test then
  586.                                         insymbol
  587.                                 until test;
  588.                                 if sy = colon then
  589.                                     insymbol
  590.                                 else
  591.                                     error(5);
  592.                                 if sy = lparent then
  593.                                     insymbol
  594.                                 else
  595.                                     error(9);
  596.                                 fieldlist(fsys + [rparent, semicolon], lsp2);
  597.                                 if displ > maxsize then
  598.                                     maxsize := displ;
  599.                                 while lsp3 <> nil do
  600.                                     begin
  601.                                         lsp4 := lsp3^.subvar;
  602.                                         lsp3^.subvar := lsp2;
  603.                                         lsp3^.size := displ;
  604.                                         lsp3 := lsp4
  605.                                     end;
  606.                                 if sy = rparent then
  607.                                     begin
  608.                                         insymbol;
  609.                                         if not (sy in fsys + [semicolon]) then
  610.                                             begin
  611.                                                 error(6);
  612.                                                 skip(fsys + [semicolon])
  613.                                             end
  614.                                     end
  615.                                 else
  616.                                     error(4);
  617.                             end;
  618.                         test := sy <> semicolon;
  619.                         if not test then
  620.                             begin
  621.                                 displ := minsize;
  622.                                 insymbol
  623.                             end
  624.                     until test;
  625.                     displ := maxsize;
  626.                     lsp^.fstvar := lsp1;
  627.                 end
  628.             else
  629.                 frecvar := nil
  630.         end; (*fieldlist*)
  631.  
  632.     begin (*typ*)
  633.         if not (sy in typebegsys) then
  634.             begin
  635.                 error(10);
  636.                 skip(fsys + typebegsys)
  637.             end;
  638.         if sy in typebegsys then
  639.             begin
  640.                 if sy in simptypebegsys then
  641.                     simpletype(fsys, fsp, fsize)
  642.                 else
  643.     (*^*)
  644.                     if sy = arrow then
  645.                         begin
  646.                             new(lsp, pointer);
  647.                             fsp := lsp;
  648.                             with lsp^ do
  649.                                 begin
  650.                                     eltype := nil;
  651.                                     size := ptrsize;
  652.                                     form := pointer
  653.                                 end;
  654.                             insymbol;
  655.                             if sy = ident then
  656.                                 begin
  657.                                     prterr := false; (*no error if search not successful*)
  658.                                     searchid([types], lcp);
  659.                                     prterr := true;
  660.                                     if lcp = nil then   (*forward referenced type id*)
  661.                                         begin
  662.                                             new(lcp, types);
  663.                                             with lcp^ do
  664.                                                 begin
  665.                                                     name := id;
  666.                                                     idtype := lsp;
  667.                                                     next := fwptr;
  668.                                                     klass := types
  669.                                                 end;
  670.                                             fwptr := lcp
  671.                                         end
  672.                                     else
  673.                                         begin
  674.                                             if lcp^.idtype <> nil then
  675.                                                 if lcp^.idtype^.form = files then
  676.                                                     error(108)
  677.                                                 else
  678.                                                     lsp^.eltype := lcp^.idtype
  679.                                         end;
  680.                                     insymbol;
  681.                                 end
  682.                             else
  683.                                 error(2);
  684.                         end
  685.                     else
  686.                         begin
  687.                             if sy = packedsy then
  688.                                 begin
  689.                                     insymbol;
  690.                                     if not (sy in typedels) then
  691.                                         begin
  692.                                             error(10);
  693.                                             skip(fsys + typedels)
  694.                                         end
  695.                                 end;
  696.     (*array*)
  697.                             if sy = arraysy then
  698.                                 begin
  699.                                     insymbol;
  700.                                     if sy = lbrack then
  701.                                         insymbol
  702.                                     else
  703.                                         error(11);
  704.                                     lsp1 := nil;
  705.                                     repeat
  706.                                         new(lsp, arrays);
  707.                                         with lsp^ do
  708.                                             begin
  709.                                                 aeltype := lsp1;
  710.                                                 inxtype := nil;
  711.                                                 form := arrays
  712.                                             end;
  713.                                         lsp1 := lsp;
  714.                                         simpletype(fsys + [comma, rbrack, ofsy], lsp2, lsize);
  715.                                         lsp1^.size := lsize;
  716.                                         if lsp2 <> nil then
  717.                                             if lsp2^.form <= subrange then
  718.                                                 begin
  719.                                                     if lsp2 = realptr then
  720.                                                         begin
  721.                                                             error(109);
  722.                                                             lsp2 := nil
  723.                                                         end
  724.                                                     else if lsp2 = intptr then
  725.                                                         begin
  726.                                                             error(149);
  727.                                                             lsp2 := nil
  728.                                                         end;
  729.                                                     lsp^.inxtype := lsp2
  730.                                                 end
  731.                                             else
  732.                                                 begin
  733.                                                     error(113);
  734.                                                     lsp2 := nil
  735.                                                 end;
  736.                                         test := sy <> comma;
  737.                                         if not test then
  738.                                             insymbol
  739.                                     until test;
  740.                                     if sy = rbrack then
  741.                                         insymbol
  742.                                     else
  743.                                         error(12);
  744.                                     if sy = ofsy then
  745.                                         insymbol
  746.                                     else
  747.                                         error(8);
  748.                                     typ(fsys, lsp, lsize);
  749.                                     repeat
  750.                                         with lsp1^ do
  751.                                             begin
  752.                                                 lsp2 := aeltype;
  753.                                                 aeltype := lsp;
  754.                                                 if inxtype <> nil then
  755.                                                     begin
  756.                                                         getbounds(inxtype, lmin, lmax);
  757.                                                         align(lsp, lsize);
  758.                                                         lsize := lsize * (lmax - lmin + 1);
  759.                                                         size := lsize
  760.                                                     end
  761.                                             end;
  762.                                         lsp := lsp1;
  763.                                         lsp1 := lsp2
  764.                                     until lsp1 = nil
  765.                                 end
  766.                             else
  767.     (*record*)
  768.                                 if sy = recordsy then
  769.                                     begin
  770.                                         insymbol;
  771.                                         oldtop := top;
  772.                                         if top < displimit then
  773.                                             begin
  774.                                                 top := top + 1;
  775.                                                 with display[top] do
  776.                                                     begin
  777.                                                         fname := nil;
  778.                                                         flabel := nil;
  779.                                                         occur := rec
  780.                                                     end
  781.                                             end
  782.                                         else
  783.                                             error(250);
  784.                                         displ := 0;
  785.                                         fieldlist(fsys - [semicolon] + [endsy], lsp1);
  786.                                         new(lsp, records);
  787.                                         with lsp^ do
  788.                                             begin
  789.                                                 fstfld := display[top].fname;
  790.                                                 recvar := lsp1;
  791.                                                 size := displ;
  792.                                                 form := records
  793.                                             end;
  794.                                         top := oldtop;
  795.                                         if sy = endsy then
  796.                                             insymbol
  797.                                         else
  798.                                             error(13)
  799.                                     end
  800.                                 else
  801.     (*set*)
  802.                                     if sy = setsy then
  803.                                         begin
  804.                                             insymbol;
  805.                                             if sy = ofsy then
  806.                                                 insymbol
  807.                                             else
  808.                                                 error(8);
  809.                                             simpletype(fsys, lsp1, lsize);
  810.                                             if lsp1 <> nil then
  811.                                                 if lsp1^.form > subrange then
  812.                                                     begin
  813.                                                         error(115);
  814.                                                         lsp1 := nil
  815.                                                     end
  816.                                                 else if lsp1 = realptr then
  817.                                                     begin
  818.                                                         error(114);
  819.                                                         lsp1 := nil
  820.                                                     end
  821.                                                 else if lsp1 = intptr then
  822.                                                     begin
  823.                                                         error(169);
  824.                                                         lsp1 := nil
  825.                                                     end
  826.                                                 else
  827.                                                     begin
  828.                                                         getbounds(lsp1, lmin, lmax);
  829.                                                         if (lmin < setlow) or (lmax > sethigh) then
  830.                                                             error(169);
  831.                                                     end;
  832.                                             new(lsp, power);
  833.                                             with lsp^ do
  834.                                                 begin
  835.                                                     elset := lsp1;
  836.                                                     size := setsize;
  837.                                                     form := power
  838.                                                 end;
  839.                                         end
  840.                                     else
  841.     (*file*)
  842.                                         if sy = filesy then
  843.                                             begin
  844.                                                 insymbol;
  845.                                                 error(399);
  846.                                                 skip(fsys);
  847.                                                 lsp := nil
  848.                                             end;
  849.                             fsp := lsp
  850.                         end;
  851.                 if not (sy in fsys) then
  852.                     begin
  853.                         error(6);
  854.                         skip(fsys)
  855.                     end
  856.             end
  857.         else
  858.             fsp := nil;
  859.         if fsp = nil then
  860.             fsize := 1
  861.         else
  862.             fsize := fsp^.size
  863.     end; (*typ*)
  864.  
  865.     procedure labeldeclaration (fsys: setofsys); {FIX!!!}
  866.         var
  867.             llp: lbp;
  868.             redef: boolean;
  869.             lbname: integer;
  870.     begin
  871.         repeat
  872.             if sy = intconst then
  873.                 with display[top] do
  874.                     begin
  875.                         llp := flabel;
  876.                         redef := false;
  877.                         while (llp <> nil) and not redef do
  878.                             if llp^.labval <> val.ival then
  879.                                 llp := llp^.nextlab
  880.                             else
  881.                                 begin
  882.                                     redef := true;
  883.                                     error(166)
  884.                                 end;
  885.                         if not redef then
  886.                             begin
  887.                                 new(llp);
  888.                                 with llp^ do
  889.                                     begin
  890.                                         labval := val.ival;
  891.                                         genlabel(lbname);
  892.                                         defined := false;
  893.                                         nextlab := flabel;
  894.                                         labname := lbname
  895.                                     end;
  896.                                 flabel := llp
  897.                             end;
  898.                         insymbol
  899.                     end
  900.             else
  901.                 error(15);
  902.             if not (sy in fsys + [comma, semicolon]) then
  903.                 begin
  904.                     error(6);
  905.                     skip(fsys + [comma, semicolon])
  906.                 end;
  907.             test := sy <> comma;
  908.             if not test then
  909.                 insymbol
  910.         until test;
  911.         if sy = semicolon then
  912.             insymbol
  913.         else
  914.             error(14)
  915.     end; (* labeldeclaration *)
  916.  
  917.     procedure constdeclaration (fsys: setofsys); {FIX!!!}
  918.         var
  919.             lcp: ctp;
  920.             lsp: stp;
  921.             lvalu: valu;
  922.     begin
  923.         if sy <> ident then
  924.             begin
  925.                 error(2);
  926.                 skip(fsys + [ident])
  927.             end;
  928.         while sy = ident do
  929.             begin
  930.                 new(lcp, konst);
  931.                 with lcp^ do
  932.                     begin
  933.                         name := id;
  934.                         idtype := nil;
  935.                         next := nil;
  936.                         klass := konst
  937.                     end;
  938.                 insymbol;
  939.                 if (sy = relop) and (op = eqop) then
  940.                     insymbol
  941.                 else
  942.                     error(16);
  943.                 Bconstant(fsys + [semicolon], lsp, lvalu);
  944.                 enterid(lcp);
  945.                 lcp^.idtype := lsp;
  946.                 lcp^.values := lvalu;
  947.                 if sy = semicolon then
  948.                     begin
  949.                         insymbol;
  950.                         if not (sy in fsys + [ident]) then
  951.                             begin
  952.                                 error(6);
  953.                                 skip(fsys + [ident])
  954.                             end
  955.                     end
  956.                 else
  957.                     error(14)
  958.             end
  959.     end; (*constdeclaration*)
  960.  
  961.     procedure typedeclaration (fsys: setofsys); {FIX!!!}
  962.         var
  963.             lcp, lcp1, lcp2: ctp;
  964.             lsp: stp;
  965.             lsize: addrrange;
  966.     begin
  967.         if sy <> ident then
  968.             begin
  969.                 error(2);
  970.                 skip(fsys + [ident])
  971.             end;
  972.         while sy = ident do
  973.             begin
  974.                 new(lcp, types);
  975.                 with lcp^ do
  976.                     begin
  977.                         name := id;
  978.                         idtype := nil;
  979.                         klass := types
  980.                     end;
  981.                 insymbol;
  982.                 if (sy = relop) and (op = eqop) then
  983.                     insymbol
  984.                 else
  985.                     error(16);
  986.                 typ(fsys + [semicolon], lsp, lsize);
  987.                 enterid(lcp);
  988.                 lcp^.idtype := lsp;
  989.       (*has any forward reference been satisfied:*)
  990.                 lcp1 := fwptr;
  991.                 while lcp1 <> nil do
  992.                     begin
  993.                         if lcp1^.name = lcp^.name then
  994.                             begin
  995.                                 lcp1^.idtype^.eltype := lcp^.idtype;
  996.                                 if lcp1 <> fwptr then
  997.                                     lcp2^.next := lcp1^.next
  998.                                 else
  999.                                     fwptr := lcp1^.next;
  1000.                             end
  1001.                         else
  1002.                             lcp2 := lcp1;
  1003.                         lcp1 := lcp1^.next
  1004.                     end;
  1005.                 if sy = semicolon then
  1006.                     begin
  1007.                         insymbol;
  1008.                         if not (sy in fsys + [ident]) then
  1009.                             begin
  1010.                                 error(6);
  1011.                                 skip(fsys + [ident])
  1012.                             end
  1013.                     end
  1014.                 else
  1015.                     error(14)
  1016.             end;
  1017.         if fwptr <> nil then
  1018.             begin
  1019.                 error(117);
  1020.                 writeln(output);
  1021.                 repeat
  1022.                     writeln(output, ' type-id ', fwptr^.name);
  1023.                     fwptr := fwptr^.next
  1024.                 until fwptr = nil;
  1025.                 if not eol then
  1026.                     write(output, ' ' : chcnt + 16)
  1027.             end
  1028.     end; (*typedeclaration*)
  1029.  
  1030.     procedure vardeclaration (fsys: setofsys); {FIX!!!}
  1031.         var
  1032.             lcp, nxt: ctp;
  1033.             lsp: stp;
  1034.             lsize: addrrange;
  1035.     begin
  1036.         nxt := nil;
  1037.         repeat
  1038.             repeat
  1039.                 if sy = ident then
  1040.                     begin
  1041.                         new(lcp, vars);
  1042.                         with lcp^ do
  1043.                             begin
  1044.                                 name := id;
  1045.                                 next := nxt;
  1046.                                 klass := vars;
  1047.                                 idtype := nil;
  1048.                                 vkind := actual;
  1049.                                 vlev := level
  1050.                             end;
  1051.                         enterid(lcp);
  1052.                         nxt := lcp;
  1053.                         insymbol;
  1054.                     end
  1055.                 else
  1056.                     error(2);
  1057.                 if not (sy in fsys + [comma, colon] + typedels) then
  1058.                     begin
  1059.                         error(6);
  1060.                         skip(fsys + [comma, colon, semicolon] + typedels)
  1061.                     end;
  1062.                 test := sy <> comma;
  1063.                 if not test then
  1064.                     insymbol
  1065.             until test;
  1066.             if sy = colon then
  1067.                 insymbol
  1068.             else
  1069.                 error(5);
  1070.             typ(fsys + [semicolon] + typedels, lsp, lsize);
  1071.             while nxt <> nil do
  1072.                 with nxt^ do
  1073.                     begin
  1074.                         align(lsp, lc);
  1075.                         idtype := lsp;
  1076.                         vaddr := lc;
  1077.                         lc := lc + lsize;
  1078.                         nxt := next
  1079.                     end;
  1080.             if sy = semicolon then
  1081.                 begin
  1082.                     insymbol;
  1083.                     if not (sy in fsys + [ident]) then
  1084.                         begin
  1085.                             error(6);
  1086.                             skip(fsys + [ident])
  1087.                         end
  1088.                 end
  1089.             else
  1090.                 error(14)
  1091.         until (sy <> ident) and not (sy in typedels);
  1092.         if fwptr <> nil then
  1093.             begin
  1094.                 error(117);
  1095.                 writeln(output);
  1096.                 repeat
  1097.                     writeln(output, ' type-id ', fwptr^.name);
  1098.                     fwptr := fwptr^.next
  1099.                 until fwptr = nil;
  1100.                 if not eol then
  1101.                     write(output, ' ' : chcnt + 16)
  1102.             end
  1103.     end; (*vardeclaration*)
  1104.  
  1105. end.